<!doctype html>
<meta charset="utf-8">
<title>PaymentHandler: Tests for PaymentInstruments</title>
<link rel="help" href="https://w3c.github.io/webpayments-payment-apps-api/#payment-instruments">
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/permissions-helper.js"></script>
<script src="../../serviceworker/resources/test-helpers.js"></script>
<script>

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'granted');
        })
      .then(() => {
          return registration.paymentManager.instruments.set(
              'test_key',
              {
                name: 'Visa ending ****4756',
                icons: [
                  {
                    'src': './resources/icon-1x.png',
                    'sizes': '32x32 48x48',
                    'type': 'image/png'
                  },
                  {
                    'src': './resources/icon-2x.png',
                    'sizes': '96x96',
                    'type': 'image/png',
                    'purpose': 'any monochrome'
                  }
                ],
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              });
        })
      .then(result => {
          assert_equals(result, undefined);
          return registration.paymentManager.instruments.get('test_key');
        })
      .then(stored_instrument => {
          assert_equals(stored_instrument.name, 'Visa ending ****4756');
          assert_equals(stored_instrument.method, 'basic-card');
          assert_equals(stored_instrument.icons.length, 2);
          assert_object_equals(stored_instrument.icons[0], {
              src: location.origin + '/payments/resources/icon-1x.png',
              sizes: '32x32 48x48',
              type: 'image/png'
            });
          assert_object_equals(stored_instrument.icons[1], {
              src: location.origin + '/payments/resources/icon-2x.png',
              sizes: '96x96',
              type: 'image/png'
            });
          assert_object_equals(stored_instrument.capabilities, {
              supportedNetworks: ['visa'],
              supportedTypes: ['credit']
            });
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments set/get methods test');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return registration.paymentManager.instruments.get('test_key');
        })
      .then(result => {
          assert_equals(result, undefined);
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments.get() should throw NotFoundError if no stored key');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'granted');
        })
      .then(() => {
          return registration.paymentManager.instruments.set(
              'test_key',
              {
                name: 'Visa ending ****4756',
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              });
        })
      .then(result => {
          assert_equals(result, undefined);
          return registration.paymentManager.instruments.delete('test_key');
        })
      .then(result => {
          assert_equals(result, true);
          return registration.paymentManager.instruments.delete('test_key');
        })
      .then(result => {
          assert_equals(result, false);
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments delete method test');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'granted');
        })
      .then(() => {
          return registration.paymentManager.instruments.set(
              'test_key',
              {
                name: 'Visa ending ****4756',
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              });
        })
      .then(result => {
          assert_equals(result, undefined);
          return registration.paymentManager.instruments.has('test_key');
        })
      .then(result => {
          assert_equals(result, true);
          return registration.paymentManager.instruments.has('unstored_test_key');
        })
      .then(result => {
          assert_equals(result, false);
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments |has| method test');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'granted');
        })
      .then(() => {
          var instruments = [
            registration.paymentManager.instruments.set(
              'test_key1',
              {
                name: 'Visa ending ****4756',
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              }),
            registration.paymentManager.instruments.set(
              'test_key2',
              {
                name: "My Bob Pay Account: john@example.com",
                method: "https://bobpay.com/"
              })
          ];
          return Promise.all(instruments);
        })
      .then(result => {
          assert_array_equals(result, [undefined, undefined]);
          return registration.paymentManager.instruments.keys();
        })
      .then(result => {
          assert_array_equals(result, ['test_key1', 'test_key2']);
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments |keys| method test');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'granted');
        })
      .then(() => {
          var instruments = [
            registration.paymentManager.instruments.set(
              'test_key1',
              {
                name: 'Visa ending ****4756',
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              }),
            registration.paymentManager.instruments.set(
              'test_key2',
              {
                name: "My Bob Pay Account: john@example.com",
                method: "https://bobpay.com/"
              })
          ];
          return Promise.all(instruments);
        })
      .then(result => {
          assert_array_equals(result, [undefined, undefined]);
          return registration.paymentManager.instruments.keys();
        })
      .then(result => {
          assert_equals(result.length, 2);
          return registration.paymentManager.instruments.clear();
        })
      .then(result => {
          assert_equals(result, undefined);
          return registration.paymentManager.instruments.keys();
        })
      .then(result => {
          assert_equals(result.length, 0);
        })
      .catch(unreached_rejection(test));
  }, 'PaymentInstruments |clear| method test');

promise_test(test => {
    var registration;
    var script_url = 'resources/empty-worker.js';
    var scope = 'resources/';

    return service_worker_unregister_and_register(test, script_url, scope)
      .then(r => {
          registration = r;
          return wait_for_state(test, registration.installing, 'activated');
        })
      .then(state => {
          assert_equals(state, 'activated');
          return PermissionsHelper.setPermission('payment-handler', 'denied');
        })
      .then(() => {
          return registration.paymentManager.instruments.set(
              'test_key',
              {
                name: 'Visa ending ****4756',
                icons: [
                  {
                    'src': './resources/icon-1x.png',
                    'sizes': '32x32 48x48',
                    'type': 'image/png'
                  },
                  {
                    'src': './resources/icon-2x.png',
                    'sizes': '96x96',
                    'type': 'image/png',
                    'purpose': 'any monochrome'
                  }
                ],
                method: 'basic-card',
                capabilities: {
                  supportedNetworks: ['visa'],
                  supportedTypes: ['credit']
                }
              });
        })
      .then(result => {
          assert_unreached();
        })
      .catch(e => {
          assert_equals(e.name, 'NotAllowedError');
        });
  }, 'Throw NotAllowedError if permission is not granted');

</script>
